#ifndef __GUI_H__
#define __GUI_H__

#include "base.h"

#define ACALLBACK


//GUI区域
struct Area {
	int _x;
	int _y;			//位置
	int _width;
	int _height;		//大小
	
	int enable;		//是否参与检测
	int visual;		//可否参与渲染
	Image back_image;	//背景图片
	Image fore_image;	//前影图片

	int _focus;		//获得焦点
	void *userdata;		//用户数据
	
	void ACALLBACK (*user_render)(struct Area *who, void *userdata);
	void ACALLBACK (*mouse_down)(struct Area *who, int button, int x, int y, void *userdata);
	void ACALLBACK (*mouse_up)(struct Area *who, int button, int x, int y, void *userdata);
	void ACALLBACK (*mouse_enter)(struct Area *who, void *userdata);
	void ACALLBACK (*mouse_leave)(struct Area *who, void *userdata);
	void ACALLBACK (*mouse_move)(struct Area *who, int x, int y, void *userdata);
	
	//发生于焦点区域
	void ACALLBACK (*key_press)(struct Area *who, int key, Uint32 unicode, void *userdata);
	void ACALLBACK (*key_up)(struct Area *who, int key, Uint32 unicode, void *userdata);
	void ACALLBACK (*key_down)(struct Area *who, int key, Uint32 unicode, void *userdata);
	
	struct Area *_child;				//子区域
	struct Area *_next;				//区域链表
};

/*	gui初始化,返回非0失败
 */
int		gui_init	();

/*	gui事件处理, 调用后会立即返回, 期间会调用相应区域的回调(如果有的事件的话)
 */
void		gui_event_idle	(struct Area *a_det);

/*	gui渲染, 这将按层次更新所有的区域和其用户绘制回调
 */
void		gui_render	();

//公共资源
Font		gui_get_font_big();
Font		gui_get_font_small();
Image		gui_get_box_bg();


/*	新建一块区域, 如果father为null, 则从根区域中创建
 *	返回区域指针, 新生成区域除了坐标大小外, 其它数据全为0
 */
struct Area *	area_new	(struct Area *father, int x, int y, int width, int height);

/*	从区域树中删除子树, 如果father 为null, 则从根中删除
 *	如果area为null, 则删除所有子树, 删除一个区域将连带删除该区域的子区域
 */
void		area_delete	(struct Area *father, struct Area *area);

/*	递归移动a及a的所有后代
 */
void area_move(struct Area *a, int dx, int dy);

/*	设置事件焦点
 */
void area_focus(struct Area *a);



struct Panel {			//面板,容器基本单位
	struct Area *_area;
	int px, py;			//相对坐标
	void *userdata;
	void ACALLBACK (*mouse_down)(struct Panel *pn, int button, int x, int y, void *userdata);
	void ACALLBACK (*mouse_up)(struct Panel *pn, int button, int x, int y, void *userdata);
	void ACALLBACK (*mouse_move)(struct Panel *pn, int x, int y, void *userdata);
	void ACALLBACK (*enter)(struct Panel *pn, void *userdata);
	void ACALLBACK (*leave)(struct Panel *pn, void *userdata);
	void ACALLBACK (*user_render)(struct Panel *pn, void *userdata);
};

//新建面板, 采用相对坐标
struct Panel *panel_new(struct Panel *father, int x, int y, int width, int height);

void panel_delete(struct Panel *father, struct Panel *pn);
//回调注册
void panel_mouse_down(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, int button, int x, int y, void *userdata));
void panel_mouse_up(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, int button, int x, int y, void *userdata));
void panel_mouse_move(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, int x, int y, void *userdata));
void panel_mouse_enter(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, void *userdata));
void panel_mouse_leave(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, void *userdata));
void panel_user_render(struct Panel *pn, void ACALLBACK (*f)(struct Panel *pn, void *userdata));
//位置函数
void panel_get_pos(struct Panel *pn, int *x, int *y);
//得到绝对坐标, 通常用于自定义渲染
void panel_get_abs_pos(struct Panel *pn, int *x, int *y);
void panel_set_pos(struct Panel *pn, int x, int y);
//尺寸
void panel_get_size(struct Panel *pn, int *w, int *h);
void panel_set_size(struct Panel *pn, int w, int h);

void panel_set_enable(struct Panel *pn, int en);
int panel_get_enable(struct Panel *pn);
void panel_set_userdata(struct Panel *pn, void *data);
void panel_set_visual(struct Panel *pn, int vi);
int panel_get_visual(struct Panel *pn);

struct Button {
	struct Area *_area;
	char *_caption;
	Font _font;
	Uint32 _font_color;
	int _status;
	
	Image but_image;
	void *userdata;
	void ACALLBACK (*click)(struct Button *bt, void *userdata);
	void ACALLBACK (*enter)(struct Button *bt, void *userdata);
	void ACALLBACK (*leave)(struct Button *bt, void *userdata);
	
};

struct Button *button_new(struct Panel *father, int x, int y,
			  int width, int height);
void button_set_caption(struct Button *bt, const char *cap);
void button_set_font(struct Button *bt, Font font);
void button_set_image(struct Button *bt, Image img);
void button_delete(struct Button *bt);
void button_clicked(struct Button *bt, void ACALLBACK (*f)(struct Button *bt, void *userdata));
void button_enter(struct Button *bt, void ACALLBACK (*f)(struct Button *bt, void *userdata));
void button_leave(struct Button *bt, void ACALLBACK (*f)(struct Button *bt, void *userdata));
void button_set_color(struct Button *bt, Uint32 color);
void button_set_userdata(struct Button *bt, void *userdata);

struct Label {
	struct Area *_area;
	char *_caption;
	Font _font;
	Uint32 _font_color;
	int _align;
};

enum _Align {
	ALIGN_LEFT,
	ALIGN_CENTER,
	ALIGN_RIGHT,
};

struct Label *label_new(struct Panel *father, const char *cap, int x, int y, int width, int height);
void label_set_caption(struct Label *lb, const char *cap);
void label_set_font(struct Label *lb, Font font);
void label_delete(struct Label *lb);
void label_set_color(struct Label *lb, Uint32 color);
void label_set_align(struct Label *lb, int align);

enum _Msg_button {
	MSG_OK = 1,
	MSG_YES = 2,
	MSG_NO = 4,
	MSG_CANCEL = 8
};

struct Msgbox {
	struct Panel *pn_window;	//面板
	struct Button *bt_ok;		//按钮s
	struct Button *bt_yes;
	struct Button *bt_no;
	struct Button *bt_cancel;
	Image _icon;			//图标
	Image _img_title;		//标题
	Image *_img_msg;		//信息行数组
	int _msg_line;			//行数
	int _button;			//按钮掩码
	
	int button_flag;		//用于鼠标事件的数据
	int old_x;
	int old_y;
	
	int ret_val;			//返回值
};

struct Msgbox *msgbox_new(char *title, char *msg, int type, int button);
int msgbox_init();
int msgbox_run(struct Msgbox *win);
void msgbox_delete(struct Msgbox *win);

struct Checker {
	struct Area *_area;
	char *_caption;
	Font _font;
	Uint32 _font_color;
	int value;
	void *userdata;
	void ACALLBACK (*change)(struct Checker *bt, int value, void *userdata);
};
struct Checker *check_new(struct Panel *father, const char *cap, int x, int y, int width, int height);
void check_set_caption(struct Checker *ck, const char *cap);
void check_set_font(struct Checker *ck, Font font);
void check_delete(struct Checker *ck);
void check_set_color(struct Checker *ck, Uint32 color);
void check_set_value(struct Checker *ck, int val);
int check_get_value(struct Checker *ck);
void check_change(struct Checker *ck, void ACALLBACK (*f)(struct Checker *bt, int value, void *userdata));

struct Input {
	struct Area *_area;
	Font _font;
	Uint32 _font_color;
	int _align;
	
	char *_text;			//文本,以'\n'为换行
	int _cursor;			//当前光标位置
	int _disp_line;			//显示开始的行
	int _need_update;		//需要更新
	Image _img_buf;			//后台缓冲(尽可能不更新)
};

struct Input *input_new(struct Panel *father, int x, int y, int width, int height);
void input_set_font(struct Input *ip, Font font);
void input_delete(struct Input *ip);
void input_set_color(struct Input *ip, Uint32 color);
void input_set_align(struct Input *ip, int align);

void input_input(struct Input *ip, const char *str);
void input_back(struct Input *ip);
void input_del(struct Input *ip);

#endif

